package com.aooci.ordercat.jsf;

import java.io.Serializable;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;

import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.event.SelectEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.aooci.ordercat.domain.DiningTable;
import com.aooci.ordercat.domain.ItemCategory;
import com.aooci.ordercat.domain.SortGroup;
import com.aooci.ordercat.domain.Takeaway;
import com.aooci.ordercat.enums.OrderType;
import com.aooci.ordercat.service.OrderOperationService;
import com.aooci.ordercat.service.PrintingService;
import com.aooci.ordercat.service.SystemParameter;
import com.aooci.ordercat.vo.CheckoutVo;
import com.aooci.ordercat.vo.ItemVo;
import com.aooci.ordercat.vo.OperatedOrderVo;
import com.aooci.ordercat.vo.OrderedItemVo;

//@ManagedBean
@RequestScoped
@Component
public class OrderOperationController implements Serializable{
	
	private static final long serialVersionUID = -1710221908503483197L;
	private static final Logger log = Logger.getLogger(OrderOperationController.class);

	@Autowired
	@Qualifier("orderOperationService")
	private transient OrderOperationService orderOperationService;
	
	@Autowired
	@Qualifier("printingService")
	private transient PrintingService printingService;


	private OperatedOrderVo operatedOrderVo;
	private ItemCategory selectedItemCategory;
	private ItemVo selectedItemVo;
	private OrderedItemVo selectedOrderedItemVo;
	
	private Date takingTime;
	private CheckoutVo checkoutVo;
	private String commandValue;
	
    public void handleCommand() {
    	System.out.println(commandValue);
    	this.commandValue = this.orderOperationService.dealCommand(operatedOrderVo, commandValue);
    }
    
    public boolean isInputTotalConfirmed(){
    	if(this.checkoutVo != null)
    		return this.orderOperationService.validateEncase(this.checkoutVo);
    	else
    		return false;
    }
	
	public void clearOrder(){
		this.orderOperationService.clearOrder(this.operatedOrderVo, this.checkoutVo);
		this.operatedOrderVo = null;
	}
	
	public void checkout(){
		this.orderOperationService.checkout(this.operatedOrderVo);
		FacesContext facesContext = FacesContext.getCurrentInstance();
		String messageBundleName = facesContext.getApplication().getMessageBundle();
		Locale locale = facesContext.getViewRoot().getLocale();
		ResourceBundle bundle = ResourceBundle.getBundle(messageBundleName, locale);
		this.printingService.printReceiptToClient(operatedOrderVo, bundle);
	}
//
//    public void updateCheckoutOnSlideEnd(SlideEndEvent event) {
//    	this.checkoutVo.setDiscountRate(event.getValue());
//    	this.orderOperationService.updateCheckoutVo(this.checkoutVo, this.operatedOrderVo);
//    	this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
//    } 
//    
    public void resetDiscountRate(){
    	this.orderOperationService.updateCheckoutVo(this.checkoutVo, this.operatedOrderVo);
    	this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
    }
    
    public void reopenOrder(){
    	this.orderOperationService.reopenOrder(this.operatedOrderVo);
    }
	
	public void printToKitchen(){
		this.printingService.printToKitchen(operatedOrderVo);
	}
	
	public void printAddingToKitchen(){
		this.printingService.printAddingToKitchen(operatedOrderVo);
	}
	
	public void createOrderForDiningTable(DiningTable diningTable){
		this.operatedOrderVo = this.orderOperationService.createDiningTableOrder(diningTable.getId(), diningTable.getNofClient());
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
	}
	

	public void createOrderForTakeaway(){
		this.operatedOrderVo = this.orderOperationService.createTakeawayOrder();
		this.takingTime = this.operatedOrderVo.getTakeaway().getTakingTimestamp().getTime();
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
	}
	
	public List<DiningTable> loadFreeDiningTables(int diningTableCategoryId){
		return this.orderOperationService.loadFreeDiningTablesByCategoryId(diningTableCategoryId);
	}
	
	public void changeTableListener(ActionEvent event){
		int targetTableId = Integer.parseInt(event.getComponent().getAttributes().get("freeTableId").toString());
		this.operatedOrderVo.setDiningTable(this.orderOperationService.changeTable(operatedOrderVo.getDiningTable(), targetTableId));
	}
	
	public void changeTakingTimeListener(ActionEvent event){
		this.operatedOrderVo.setTakeaway(this.orderOperationService.changeTakingTime(this.operatedOrderVo.getTakeaway(), this.takingTime));
	}
	
	public void loadOrderForDiningTable(DiningTable diningTable){
		this.operatedOrderVo = this.orderOperationService.loadDiningTableOrder(diningTable.getId());
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
		log.info("Load order for table: " + diningTable.getLabel());
	}
	
	public void loadOrderForTakeaway(Takeaway takeaway){
		this.operatedOrderVo = this.orderOperationService.loadTakeawayOrder(takeaway.getId());
		this.takingTime = this.operatedOrderVo.getTakeaway().getTakingTimestamp().getTime();
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
	}
	
	public void modifyOrderedItem(OrderedItemVo orderedItemVo){
		this.orderOperationService.updateOrderedItem(this.operatedOrderVo, orderedItemVo);
		this.selectedOrderedItemVo = orderedItemVo;
		this.orderOperationService.updateCheckoutVo(this.checkoutVo, this.operatedOrderVo);
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
	}
	
	public void discardOrderForDiningTable(){
		this.orderOperationService.discardDiningTableOrder(this.operatedOrderVo.getDiningTable().getId());
		log.info("Discard order for table: " + this.operatedOrderVo.getDiningTable().getLabel());
		this.operatedOrderVo = null;
	}

	public void discardOrderForTakeaway(){
		this.orderOperationService.discardTakeawayOrder(this.operatedOrderVo.getTakeaway().getId());
		this.operatedOrderVo = null;
	}
	
	public void disorderItem(){
		this.orderOperationService.disorderItem(this.operatedOrderVo, this.selectedOrderedItemVo.getEntityId());
		this.orderOperationService.updateCheckoutVo(this.checkoutVo, this.operatedOrderVo);
		this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
	}
	
    public void onItemSelect(SelectEvent event) {  
        this.orderOperationService.orderItem(this.operatedOrderVo, this.selectedItemVo.getId());
        this.orderOperationService.updateCheckoutVo(this.checkoutVo, this.operatedOrderVo);
        this.checkoutVo = this.orderOperationService.loadCheckoutVo(this.operatedOrderVo.getOrdercat().getId());
    }
    
    public void onOrderedItemSelect(SelectEvent event) {  
        this.orderOperationService.orderItem(this.operatedOrderVo, this.selectedItemVo.getId());
    }
    
	public List<ItemVo> getItems() {
		if(this.selectedItemCategory != null)
			return this.orderOperationService.loadItemsByItemCategoryId(this.selectedItemCategory.getId());
		else 
			return this.orderOperationService.loadItemsByItemCategoryId(SystemParameter.DEFAULT_ITEM_CATEGORY_ID);
	}
	
	public List<OrderedItemVo> getOrderedItems(){
		if(this.operatedOrderVo != null){
			return this.orderOperationService.loadOrderedItems(this.operatedOrderVo.getOrdercat().getId());
		}
		return null;
	}
	
	public List<ItemCategory> getItemCategories(int displayZone) {
		return this.orderOperationService.loadItemCategoriesByDisplayZone(displayZone);
	}
	
	public List<SortGroup> getServiceGroups(){
		return this.orderOperationService.loadKitchenPrintableSortGroups();
	}
	
	public boolean isDisplaiedForDiningHall(){
		return this.operatedOrderVo == null? false : this.operatedOrderVo.getOrdercat().getType().equals(OrderType.DINING_HALL);
	}

	public boolean isDisplaiedForTakeaway(){
		return this.operatedOrderVo == null? false : this.operatedOrderVo.getOrdercat().getType().equals(OrderType.TAKEAWAY);
	}

	/**
	 * @return the selectedItemVo
	 */
	public ItemVo getSelectedItemVo() {
		return selectedItemVo;
	}

	/**
	 * @param selectedItemVo the selectedItemVo to set
	 */
	public void setSelectedItemVo(ItemVo selectedItemVo) {
		this.selectedItemVo = selectedItemVo;
	}

	/**
	 * @return the operatedOrderVo
	 */
	public OperatedOrderVo getOperatedOrderVo() {
		return operatedOrderVo;
	}

	/**
	 * @param operatedOrderVo the operatedOrderVo to set
	 */
	public void setOperatedOrderVo(OperatedOrderVo operatedOrderVo) {
		this.operatedOrderVo = operatedOrderVo;
	}

	/**
	 * @return the selectedOrderedItemVo
	 */
	public OrderedItemVo getSelectedOrderedItemVo() {
		return selectedOrderedItemVo;
	}

	/**
	 * @param selectedOrderedItemVo the selectedOrderedItemVo to set
	 */
	public void setSelectedOrderedItemVo(OrderedItemVo selectedOrderedItemVo) {
		this.selectedOrderedItemVo = selectedOrderedItemVo;
	}

	/**
	 * @return the takingTime
	 */
	public Date getTakingTime() {
		return takingTime;
	}

	/**
	 * @param takingTime the takingTime to set
	 */
	public void setTakingTime(Date takingTime) {
		this.takingTime = takingTime;
	}

	/**
	 * @return the checkoutVo
	 */
	public CheckoutVo getCheckoutVo() {
		return this.checkoutVo;
	}

	/**
	 * @param checkoutVo the checkoutVo to set
	 */
	public void setCheckoutVo(CheckoutVo checkoutVo) {
		this.checkoutVo = checkoutVo;
	}

	/**
	 * @return the selectedItemCategory
	 */
	public ItemCategory getSelectedItemCategory() {
		return selectedItemCategory;
	}

	/**
	 * @param selectedItemCategory the selectedItemCategory to set
	 */
	public void setSelectedItemCategory(ItemCategory selectedItemCategory) {
		this.selectedItemCategory = selectedItemCategory;
	}

	/**
	 * @return the commandValue
	 */
	public String getCommandValue() {
		return commandValue;
	}

	/**
	 * @param commandValue the commandValue to set
	 */
	public void setCommandValue(String commandValue) {
		this.commandValue = commandValue;
	}

}
